#include "editor_selection.h"
#include "editor_main.h"
#include "editor_brush.h"

#include "ui/ui_manager.h"
#include "ui/sprite_set.h"
#include "application/game_script.h"

#include "vfs/vfs.h"
#include "script/file_list.h"
#include "script/scripthelper.h"

#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging
#include "util/timer.h"		    // logging

#include <algorithm>
#include <cassert>
using namespace script;
using namespace LuaPlus;

using namespace editor;

TextSelect::TextSelect(EditorBrush*	pBrush, const std::string& Name) :
	UISelection(pBrush, Name)
{
	for (int i=0; i<WIDGET_C; i++)
		m_WidgetA[i]=0;

	m_pPanel = ui::UIManager::Instance().GetPanel("editor_selection");
	if (!m_pPanel)
		m_pPanel = ui::UIManager::Instance().AddPanel("ui/editor_selection.ui");

	if (m_pPanel)
	{
		m_pPanel->SetTextA(Name);
	} else
	{
	}

	Show(m_RenderName);
}

TextSelect::~TextSelect()
{
	Hide();
	if (m_pPanel)
	{
		if (ui::UIWidget* pWidget = m_pPanel->GetWidgetByName("ArrowUp"))
			pWidget->SetReleaseLMBEventDg(0);
		if (ui::UIWidget* pWidget = m_pPanel->GetWidgetByName("ArrowDown"))
			pWidget->SetReleaseLMBEventDg(0);
		if (ui::UIWidget* pWidget = m_pPanel->GetWidgetByName("Exit"))
			pWidget->SetReleaseLMBEventDg(0);

		for (int i=0; i<WIDGET_C; i++)
		{
			if (m_WidgetA[i])
				m_WidgetA[i]->SetReleaseLMBEventDg(0);
		}
	}
}

void	TextSelect::Show(bool	RenderName)
{
	m_RenderName = RenderName;
	if (m_pPanel)
	{
		m_pPanel->SetIsVisible(true);

		ui::UIManager::Instance().PushPanelToFront(m_pPanel);
		m_pPanel->SetIsVisible(true);

		if (ui::UIWidget* pWidget = m_pPanel->GetWidgetByName("ArrowUp"))
			pWidget->SetReleaseLMBEventDg(UI_DELEGATE(TextSelect, OnScrollUp));
		if (ui::UIWidget* pWidget = m_pPanel->GetWidgetByName("ArrowDown"))
			pWidget->SetReleaseLMBEventDg(UI_DELEGATE(TextSelect, OnScrollDown));
		if (ui::UIWidget* pWidget = m_pPanel->GetWidgetByName("Exit"))
			pWidget->SetReleaseLMBEventDg(UI_DELEGATE(TextSelect, OnHide));

		for (int i=0; i<WIDGET_C; i++)
		{
			m_WidgetA[i] = m_pPanel->GetWidgetByNameEx("Entry%i", i+1);
		}
		UpdateEntries();
	}
}

void	TextSelect::Reset()
{
	m_Entries.resize(0);
}

void	TextSelect::UpdateEntries()
{
	for (unsigned int i=0; i<WIDGET_C; i++)
	{
		if (!m_WidgetA[i]) 
			continue;
		int	SpriteI = m_Offset + i;
		if (SpriteI < (int)m_Entries.size())
		{
			m_WidgetA[i]->SetTextA(m_Entries[SpriteI]);
			m_WidgetA[i]->SetReleaseLMBEventDg(UI_DELEGATE(TextSelect, OnElementSelected));		
		} else
		{
			m_WidgetA[i]->SetTextA("");
			m_WidgetA[i]->SetReleaseLMBEventDg(UI_DELEGATE(TextSelect, OnHide));
		}
	}
}



void	TextSelect::Tick(float dt)
{
	if (m_ToClose)
	{
		m_ToClose = false;
		Hide();
	}


}


void	TextSelect::FromList(const std::vector<std::string>& List)
{
	Reset();
	for ( int i=0; i<(int)List.size(); i++)
	{
		m_Entries.push_back(List[i]);
	}
	UpdateEntries();
}

void	TextSelect::FromDirectory(const std::string& Directory, bool BaseName)
{
	Reset();
	script::FileList		List;
	List.Build(Directory);
	for ( int i=0; i<List.GetFileC(); i++)
	{
		if (BaseName)
		{
			m_Entries.push_back(vfs::VFS::GetBaseName(List.GetFileName(i)));
		} else
		{
			m_Entries.push_back(List.GetFileName(i	));
		}
	}
	UpdateEntries();
}

void		TextSelect::Scroll(int Dir)
{
	if (Dir < 0)
	{
		m_Offset--;
	} else
	{
		m_Offset++;
	}

	UTIL_CLAMP(m_Offset, 0, UTIL_HIGH(0, (int)m_Entries.size()-WIDGET_C));
	UpdateEntries();
}

void DELEGATE_CALL	TextSelect::OnElementSelected(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	if (m_pBrush)
	{
		m_pBrush->UpdateSelection(pWidget->GetOrigTextA());
		m_ToClose = true;
	}
}
void DELEGATE_CALL	TextSelect::OnHide(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	Hide();
	if(m_pBrush)
		m_pBrush->SetDone();
}
